package org.common.utils;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.common.rsa.RSAKeyCreater;


public class RSAUtil {
	public static Cipher cipher;
    public static X509EncodedKeySpec pubX509;
    public static PKCS8EncodedKeySpec priPKCS8;
    public static KeyFactory keyFactory;
    public static PublicKey pubKey;
    public static PrivateKey privKey;
    
    public String encryptData(final String data, final PublicKey publicKey) {
        String encryptString = "";
        try {
            (RSAUtil.cipher = Cipher.getInstance("RSA")).init(1, publicKey);
            final byte[] dataToEncrypt = data.getBytes("utf-8");
            final byte[] encryptedData = RSAUtil.cipher.doFinal(dataToEncrypt);
            encryptString = Base64.encodeBase64String(encryptedData);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return encryptString;
    }
    
    public static String encryptData(final String data, final boolean action) {
        Security.addProvider(new BouncyCastleProvider());
        String encryptData = "";
        try {
            final RSAUtil reRsaUtil = new RSAUtil();
            RSAUtil.keyFactory = KeyFactory.getInstance("RSA", "BC");
            // 加密
            if (action) {
                RSAUtil.pubX509 = new X509EncodedKeySpec(Base64.decodeBase64(RSAKeyCreater.getPublicKeyRedis()));
                RSAUtil.pubKey = RSAUtil.keyFactory.generatePublic(RSAUtil.pubX509);
                encryptData = reRsaUtil.encryptData(data, RSAUtil.pubKey);
            } else {
            	// 解密
                RSAUtil.priPKCS8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(RSAKeyCreater.getPrivateKeyRedis()));
                RSAUtil.privKey = RSAUtil.keyFactory.generatePrivate(RSAUtil.priPKCS8);
                encryptData = reRsaUtil.decryptData(data, RSAUtil.privKey);
            }
        }
        catch (Exception e1) {
            e1.printStackTrace();
        }
        return encryptData;
    }
    
    public String decryptData(final String data, final PrivateKey privateKey) {
        String srcData = "";
        try {
            (RSAUtil.cipher = Cipher.getInstance("RSA")).init(2, privateKey);
            final byte[] descryptData = Base64.decodeBase64(data);
            final byte[] descryptedData = RSAUtil.cipher.doFinal(descryptData);
            srcData = new String(descryptedData, "utf-8");
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return srcData;
    }
    
    public static void main(final String[] args) throws Exception {
        Security.addProvider(new BouncyCastleProvider());
        final String[] strings = RSAKeyCreater.createKeyPairs();
        RSAUtil.pubX509 = new X509EncodedKeySpec(Base64.decodeBase64(strings[0]));
        RSAUtil.priPKCS8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(strings[1]));
        RSAUtil.keyFactory = KeyFactory.getInstance("RSA", "BC");
        RSAUtil.pubKey = RSAUtil.keyFactory.generatePublic(RSAUtil.pubX509);
        RSAUtil.privKey = RSAUtil.keyFactory.generatePrivate(RSAUtil.priPKCS8);
        final RSAUtil rsaUtil = new RSAUtil();
        final String data = "aabbccddee";
        System.out.println("解密前data=" + data);
        String encryptData = null;
        if (RSAUtil.pubKey != null && data != null && !data.equals("")) {
            encryptData = rsaUtil.encryptData(data, RSAUtil.pubKey);
            System.out.println("公钥解密Data=" + encryptData);
        }
        String descryptData = null;
        if (RSAUtil.privKey != null && encryptData != null && !encryptData.equals("")) {
            descryptData = rsaUtil.decryptData(encryptData, RSAUtil.privKey);
            System.out.println("私钥解密Data=" + descryptData);
        }
    }
    
    static {
        RSAUtil.cipher = null;
        RSAUtil.pubX509 = null;
        RSAUtil.priPKCS8 = null;
        RSAUtil.keyFactory = null;
        RSAUtil.pubKey = null;
        RSAUtil.privKey = null;
    }
}
